//---------------------------------------------------------------------
// Copyright (C) 2010 - Cobalt Solution / Sebastien Leon              |
//---------------------------------------------------------------------
// This software is under dual licence: commercial licence + GPL v3   |
// To keep closed your modification of this software, you need to     |
// contact me to obtain a commercial licence.                         |
// Any other derivated work should remain Open Source.                |
// Contact me for a licence, a question or if you want to commit      |
// your code to the main tree: seb at cobaltsolutions dot info        |
//---------------------------------------------------------------------

#include "FTPThread.h"
#include "Core.h"

#include <QTimer>

FTPThread::FTPThread(Core& core, Loom& loom, int fileToUpload):
  QThread (&core),
  mr_core ( core),
  mr_loom ( loom),
  m_ok    (false),
  m_fileID(fileToUpload)
{
  connect (this, SIGNAL(finished()),                  this, SLOT(Terminated ()));
  connect (this, SIGNAL(ThisTerminated(FTPThread&)), &core, SLOT(UnlockResource(FTPThread&)));

  // We lock it now otherwise if there is a transfer in progress, the resource
  // could be removed before this thread could use it !
  m_src.setFileName(core.GetAndLockResource(fileToUpload));
}
//----------------------------------------------------
void FTPThread::Terminated()
{
  qDebug() << "Thread termine...";
  emit ThisTerminated(*this);
}
//----------------------------------------------------
void FTPThread::TimeOut ()
{
  // Are we still in connexion state after all this time ?
  // if yes, then abort...
  qDebug() << "TimeOut Detected...";
  if (m_ftp.currentCommand() == QFtp::ConnectToHost)
  {
    // Msg:
    emit TransferInProgress(Loom::e_errorFTP, QString::null, 1.0); // update will be done by main Thread
    mr_loom.AddLogEntry (MsgTitle(), "Loomfeed ne peut se connecter au metier. (delai d'attente depasse)", QMessageBox::Critical);
    m_ftp.abort();
    m_src.close();
    terminate ();
  }
}
//----------------------------------------------------
const QString FTPThread::GetTargetName() const
{
  return mr_core.GetResourceName(m_fileID);
}
//----------------------------------------------------
QString FTPThread::MsgTitle()
{
  return QString("TRANSFERT DE %1").arg(mr_core.GetResourceName(m_fileID));
}
//----------------------------------------------------
void FTPThread::run()
{
  // Open the file to Upload in ReadOnly mode and initiate the transfer...
  QString dst (mr_core.GetResourceName(m_fileID));
  qDebug() << "Thread d'Upload lance...";
  if (m_src.open(QIODevice::ReadOnly))
  {
    connect(&m_ftp, SIGNAL(commandFinished     (int,    bool  )), SLOT(FtpCommandFinished     (int,    bool  )));
    connect(&m_ftp, SIGNAL(dataTransferProgress(qint64, qint64)), SLOT(FtpDataTransferProgress(qint64, qint64)));
    connect(&m_ftp, SIGNAL(done(bool)),                           SLOT(Done(bool)));
    connect(  this, SIGNAL(TransferInProgress (const int, const QString&, const float)),
          &mr_loom, SLOT  (TransferInProgress (const int, const QString&, const float)));

    QTimer::singleShot(15000, this, SLOT(TimeOut())); // 15 seconds of timeout

    // Everything is ready to initiate the transfert
    m_ftp.connectToHost   (mr_loom.Address().toString());
    m_ftp.setTransferMode (QFtp::Active);
    m_ftp.login           (mr_loom.Login(), mr_loom.Password());
    m_ftp.cd              (mr_loom.DstPath());
    m_ftp.put             (&m_src, dst, QFtp::Binary);
    m_ftp.close           ();

    emit TransferInProgress(Loom::e_connectFTP, mr_core.GetResourceName(m_fileID), 0.0); // update will be done by main Thread

    exec();
  }
  else
  {
    qDebug() << "Impossible d'ouvrir le fichier...";
    mr_loom.AddLogEntry (MsgTitle(), "Erreur lors de l'acces au fichier a transferer. (disque plein ? Pb de droit d'acces ?)", QMessageBox::Critical);
  }
}
//----------------------------------------------------
void FTPThread::AbortTransfer()
{
  m_ftp.abort();
  m_src.close();
  // Msg:
  mr_loom.AddLogEntry (MsgTitle(), "Annulation du transfert sur requete de Loomfeed.", QMessageBox::Warning);
}
//----------------------------------------------------
void FTPThread::FtpCommandFinished (int, bool error )
{
  if (m_ftp.currentCommand() == QFtp::ConnectToHost)
  {
    if (error) mr_loom.AddLogEntry (MsgTitle(), QString("Erreur de connection au controleur.[%1]").arg(m_ftp.errorString()), QMessageBox::Critical);
  }
  if (m_ftp.currentCommand() == QFtp::Login)
  {
    if (error) mr_loom.AddLogEntry (MsgTitle(), QString("Erreur d'authentification.[%1]").arg(m_ftp.errorString()), QMessageBox::Critical);
  }
  if (m_ftp.currentCommand() == QFtp::Cd)
  {
    if (error) mr_loom.AddLogEntry (MsgTitle(), QString("Erreur d'acces au repertoire cible.[%1]").arg(m_ftp.errorString()), QMessageBox::Critical);
  }
  if (m_ftp.currentCommand() == QFtp::Put)
  {
    if (error)
    {
      mr_loom.AddLogEntry (MsgTitle(), QString("Transfert interrompu. ATTENTION, %2 n'est pas complet sur la machine cible...[%1]").arg(m_ftp.errorString()).arg(mr_core.GetResourceName(m_fileID)), QMessageBox::Critical);
    } else {
      mr_loom.AddLogEntry (MsgTitle()+" - SUCCES", QString::null, QMessageBox::Information);
      m_ok = true;
    }
    m_src.close();
    emit TransferInProgress(error ? Loom::e_errorFTP : Loom::e_okFTP, QString::null, 1.0); // update will be done by main Thread
  } 
}
//----------------------------------------------------
void FTPThread::FtpDataTransferProgress(qint64 done, qint64 total)
{
  float donef = (float)done/total;
  emit TransferInProgress(Loom::e_okFTP, QString::null, donef); // update will be done by main Thread
}
//----------------------------------------------------
void FTPThread::Done (bool err)
{
  m_src.close();
  exit(err?1:0);
}
